﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrainTechLLC.ThreadSafeObjects;
using System.Runtime.Serialization;

namespace BrainTechLLC
{
    [Serializable]
    [DataContract]
    public class CommaList : INotifyPropertyChanged
    {
        public CommaList() { }
        public CommaList(params string[] strings)
        {
            foreach (string s in strings)
                AddValue(s);
        }

        [DataMember]
        public string _value;

        [NonSerialized]
        protected List<string> _values;

        [NonSerialized]
        public bool _changed;

        public string Value
        {
            get
            {
                if (_changed)
                    _value = CreateString();
                return _value;
            }
            set
            {
                if (_value != value)
                {
                    _value = value;
                    _values = null;
                    OnPropertyChanged(this, new PropertyChangedEventArgsEx("Value"));
                }
            }
        }

        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged(object sender, PropertyChangedEventArgsEx args)
        {
            if (PropertyChanged != null)
            {
                args.ChildObject = sender;
                PropertyChanged(this, args);
            }
        }

        public string CreateString()
        {
            if (_values == null || _values.Count == 0)
                return string.Empty;

            return _values.BuildList("~", (s) => s);
        }


        public List<string> ReadOnlyList
        {
            get
            {
                if (_values == null)
                {
                    lock (this)
                    {
                        if (_values == null)
                        {
                            _values = new List<string>();

                            if (!string.IsNullOrEmpty(_value))
                            {
                                string[] strings = _value.Split("~".ToCharArray());

                                foreach (string s in strings)
                                    _values.Add(s);
                            }
                        }
                    }
                }
                return new List<string>(_values);
            }
        }

        public List<T> GetReadOnlyList<T>()
        {
            List<T> results = new List<T>();
            var list = ReadOnlyList;
            foreach (var item in list)
            {
                results.Add((T)Convert.ChangeType(item, typeof(T), null));
            }
            return results;
        }

        public void ModifyValue(string old, string newString)
        {
            int idx = _values.IndexOf(old);
            if (idx >= 0)
            {
                _values[idx] = newString;
                _changed = true;
            }
            OnPropertyChanged(this, new PropertyChangedEventArgsEx("Value"));
        }

        public bool ContainsValue(string s)
        {
            if (_values == null)
                return false;

            return (_values.Contains(s));
        }

        public void AddValue(string s)
        {
            if (_values == null)
                Interlocked.CompareExchange<List<string>>(ref _values, new List<string>(), null);

            _values.Add(s);
            _changed = true;

            OnPropertyChanged(this, new PropertyChangedEventArgsEx("Value"));
        }

        public override string ToString()
        {
            return Value == null ? string.Empty : Value.Replace("~", ",");
        }

        public static CommaList CreateFromCommaDelimited(string s)
        {
            CommaList result = new CommaList();
            string[] strings = s.Split(",".ToCharArray());
            foreach (string str in strings)
            {
                result.AddValue(str);
            }
            return result;
        }
    }

}
